#include "Vector3.h"

Vector3 Vector3::normalize()
{
    double len = getLength();
    if (len)
    {
        x /= len;
        y /= len;
        z /= len;
    }

    return *this;
}

Vector3 vector3_normalize(Vector3 V)
{
    double len = V.getLength();
    if (len)
        return Vector3(V.getX() / len, V.getY() / len, V.getZ() / len);
    else
        return V;
}

/*Vector3 Vector3_normalize(Vector3 *V)
{
    Vector3 res;
    double len = V->getLength();
    if (len)
    {
        res.x = V->x / len;
        res.y = V->y / len;
        res.z = V->z / len;
    }

    return res;
}*/

Vector3 Vector3::rotateGrad(Vector3 V, double angle)
{
    double a = pi * angle / 180;
    Vector3 ve(0, 0, 0);
    ve = vector3_normalize(*this);
    *this = vector3_normalize(vector3_normalize((*this * V) * *this) * sin(a) + (vector3_normalize(*this) * cos(a))) * this->getLength();
         //говно твой код еби очко коня
    return *this;
}

Vector3 vector3_rotateGrad(Vector3 V1, Vector3 V2, double angle)
{
    double a = pi * angle / 180;

    return ((vector3_normalize((V1 * V2) * V1) * sin(a)) + (vector3_normalize(V1) * cos(a))) * V1.getLength();
}

/*Vector3 Vector3_rotateGrad(Vector3 *V1, Vector3 V2, double angle)
{
    double a = pi * angle / 180;

    return ((Vector3_normalize((V1 * V2) * V1) * sin(a)) + (Vector3_normolize(this) * cos(a))) * V1->getLength();
}

Vector3 Vector3_rotateGrad(Vector3 V1, Vector3 *V2, double angle)
{
    double a = pi * angle / 180;

    return ((Vector3_normalize((V1 * V2) * V1) * sin(a)) + (Vector3_normalize(this) * cos(a))) * V1.getLength();
}

Vector3 Vector3_rotateGrad(Vector3 *V1, Vector3 *V2, double angle)
{
    double a = pi * angle / 180;

    return ((Vector3_normalize((V1 * V2) * V1) * sin(a)) + (Vector3_normalize(V1) * cos(a))) * V1->getLength();
}*/

Vector3 Vector3::rotateRad(Vector3 V, double angle)
{
    *this = (vector3_normalize((*this * V) * *this) * sin(angle)) + (vector3_normalize(V) * cos(angle)) * this->getLength();

    return *this;
}

Vector3 vector3_rotateRad(Vector3 V1, Vector3 V2, double angle)
{
    return ((vector3_normalize((V1 * V2) * V1) * sin(angle)) + (vector3_normalize(V1) * cos(angle))) * V1.getLength();
}

/*Vector3 Vector3_rotateRad(Vector3 *V1, Vector3 V2, double angle)
{
    Vector3 V1(this);
    *this = ((Vector3_normalize((V1 * V2) * V1) * sin(angle)) + (Vector3_normalize(V1) * cos(angle))) * V1.getLength();

    return *this;
}

Vector3 Vector3_rotateRad(Vector3 V1, Vector3 V2, double angle)
{
    Vector3 V1(this);
    *this = ((Vector3_normalize((V1 * V2) * V1) * sin(angle)) + (Vector3_normalize(V1) * cos(angle))) * len;

    return *this;
}*/

Vector3 Vector3::operator = (Vector3 V)
{
    x = V.x;
    y = V.y;
    z = V.z;

    return *this;
}

/*Vector3 Vector3::operator = (Vector3 *V)
{
    x = V->x;
    y = V->y;
    z = V->z;

    return *this;
}*/

/*Vector3 operator = (Vector3 *V1, Vector3 V2)
{
    V1->x = V2.x;
    V1->y = V2.y;
    V1->z = V2.z;

    return *this;
}*/

Vector3 Vector3::operator += (Vector3 V)
{
    x = x + V.x;
    y = y + V.y;
    z = z + V.z;

    return *this;
}

/*Vector3 Vector3::operator += (Vector3 *V)
{
    x = x + V->x;
    y = y + V->y;
    z = z + V->z;

    return *this;
}*/

Vector3 Vector3::operator += (double R)
{
    Vector3 norm(x, y, z);
    norm.normalize();
    x = x + norm.x * R;
    y = y + norm.y * R;
    z = z + norm.z * R;

    return *this;
}

/*Vector3 Vector3::operator += (double *R)
{
    Vector3 norm(x, y, z);
    norm.normolize();
    x = x + norm.x * *R;
    y = y + norm.y * *R;
    z = z + norm.z * *R;

    return *this;
}*/

Vector3 Vector3::operator -= (Vector3 V)
{
    x = x - V.x;
    y = y - V.y;
    z = z - V.z;

    return *this;
}

/*Vector3 Vector3::operator -= (Vector3 *V)
{
    x = x - V->x;
    y = y - V->y;
    z = z - V->z;

    return *this;
}*/

Vector3 Vector3::operator -= (double R)
{
    Vector3 norm(x, y, z);
    norm.normalize();
    x = x - norm.x * R;
    y = y - norm.y * R;
    z = z - norm.z * R;

    return *this;
}

/*Vector3 Vector3::operator -= (double *R)
{
    Vector3 norm(x, y, z);
    norm.normolize();
    x = x - norm.x * *R;
    y = y - norm.y * *R;
    z = z - norm.z * *R;

    return *this;
}*/

Vector3 Vector3::operator *= (Vector3 V)
{
    x = y * V.z - z * V.y;
    y = z * V.x - x * V.z;
    z = x * V.y - y * V.x;

    return *this;
}

/*Vector3 Vector3::operator *= (Vector3 *V)
{
    x = y * V->z - z * V->y;
    y = z * V->x - x * V->z;
    z = x * V->y - y * V->x;

    return *this;
}*/

Vector3 Vector3::operator *= (double R)
{
    x = x * R;
    y = y * R;
    z = z * R;

    return *this;
}

/*Vector3 Vector3::operator *= (double *R)
{
    x = x * *R;
    y = y * *R;
    z = z * *R;

    return *this;
}*/

Vector3 Vector3::operator /= (double R)
{
    x = x / R;
    y = y / R;
    z = z / R;
    return *this;
}

/*Vector3 Vector3::operator /= (double *R)
{
    if (!R)
        return 0;
    x = x / *R;
    y = y / *R;
    z = z / *R;

    return *this;
}*/

Vector3 Vector3::operator + (Vector3 V)
{
    return Vector3(x + V.x, y + V.y, z + V.z);
}

/*Vector3 Vector3::operator + (Vector3 *V)
{
    Vector3 res;
    res.x = x + V->x;
    res.y = y + V->y;
    res.z = z + V->z;

    return res;
}*/

Vector3 Vector3::operator + (double R)
{
    Vector3 norm(vector3_normalize(*this));
    return Vector3(x + norm.x * R, y + norm.y * R, z + norm.z * R);
}

/*Vector3 Vector3::operator + (double *R)
{
    Vector3 norm(x, y, z);
    norm.normolize();
    Vector3 res;
    res.x = x + norm.x * *R;
    res.y = y + norm.y * *R;
    res.z = z + norm.z * *R;

    return res;
}*/

Vector3 Vector3::operator - (Vector3 V)
{
    return Vector3(x - V.x, y - V.y, z - V.z);
}

/*Vector3 Vector3::operator - (Vector3 *V)
{
    Vector3 res;
    res.x = x - V->x;
    res.y = y - V->y;
    res.z = z - V->z;

    return res;
}*/

Vector3 Vector3::operator - (double R)
{
    Vector3 norm(vector3_normalize(*this));
    return Vector3(x - norm.x * R, y - norm.y * R, z - norm.z * R);
}

/*Vector3 Vector3::operator - (double *R)
{
    Vector3 norm(x, y, z);
    norm.normolize();
    Vector3 res;
    res.x = x - norm.x * *R;
    res.y = y - norm.y * *R;
    res.z = z - norm.z * *R;

    return res;
}*/

Vector3 Vector3::operator - ()
{
    return Vector3(-x, -y, -z);
}

Vector3 Vector3::operator * (Vector3 V)
{
    return Vector3(y * V.z - z * V.y, z * V.x - x * V.z, x * V.y - y * V.x);
}

/*Vector3 Vector3::operator * (Vector3 *V)
{
    Vector3 res;
    res.x = y * V->z - z * V->y;
    res.y = z * V->x - x * V->z;
    res.z = x * V->y - y * V->x;

    return res;
}

friend Vector3 operator * (Vector3 *V1, Vector3 V2)
{
    Vector3 res;
    res.x = V1->y * V2.z - V1->z * V2.y;
    res.y = V1->z * V2.x - V1->x * V2.z;
    res.z = V1->x * V2.y - V1->y * V2.x;

    return res;
}*/

Vector3 Vector3::operator * (double R)
{
    return Vector3(x * R, y * R, z * R);
}

/*Vector3 Vector3::operator * (double *R)
{
    Vector3 res;
    res.x = x * *R;
    res.y = y * *R;
    res.z = z * *R;

    return res;
}*/

Vector3 Vector3::operator / (double R)
{
    return Vector3(x / R, y / R, z / R);
}

/*Vector3 Vector3::operator / (double *R)
{
    if (!R)
        return 0;
    Vector3 res;
    res.x = x / *R;
    res.y = y / *R;
    res.z = z / *R;

    return res;
}*/

double Vector3::operator % (Vector3 V)
{
    return x * V.x + y * V.y + z * V.z;
}

/*double Vector3::operator % (Vector3 *V)
{
    return x * V->x + y * V->y + z * V->z;
}*/

int Vector3::operator == (Vector3 V)
{
    return x * V.x + y * V.y + z * V.z;
}

/*int Vector3::operator == (Vector3 *V)
{
    return (x == V.x && y == V.y && z = V.z);
}*/

int Vector3::operator != (Vector3 V)
{
    if (x == V.x)
        if (y == V.y)
            if (z == V.z)
                return 0;
            else
                return 4;
        else
            if (z == V.z)
                return 2;
            else
                return 6;
    else
        if (y == V.y)
            if (z == V.z)
                return 1;
            else
                return 5;
        else
            if (z == V.z)
                return 3;
            else
                return 7;
}

/*int Vector3::operator != (Vector3 *V)
{
    if (x == V->x)
        if (y == V->y)
            if (z == V->z)
                return 0;
            else
                return 4;
        else
            if (z == V->z)
                return 2;
            else
                return 6;
    else
        if (y == V->y)
            if (z == V->z)
                return 1;
            else
                return 5;
        else
            if (z == V->z)
                return 3;
            else
                return 7;
}*/
